import java.util.*;

public class Main {
    public static void main(String[] args) {
        Map<String, Integer> cnt = new HashMap<>();

        String s = "ababcdefd                 ";
        String sub = s.substring(0, 2);
        int c = cnt.merge(sub, 1, Integer::sum);
        sub = s.substring(2, 4);
        c = cnt.merge(sub, 1, Integer::sum   );
        
        int cc = Integer.sum(100, 11);
        System.out.println(c);
    }
    public static void main22(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int a = 1;
        char s = 'a';
        String.valueOf(s);
        System.out.println(String.valueOf(a));
        Scanner in = new Scanner(System.in);

        System.out.println(Math.pow(5.0, 13.0));

    }
    public static void main999(String[] args) {
        Scanner in = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
        int n = in.nextInt();
        int m = in.nextInt();

        char[][] board = new char[n][m];
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < m; ++j) {
                //此时我们先录入字符串，之后 截取第一个字符
                board[i][j] = in.next().charAt(0);
            }
        }

        //之后使用map来记录
        Map<Character, Integer> map = new HashMap<>();
        String sb = "love                ";
        int k = 4;
        for (char tmp : sb.toCharArray()) {
            map.put(tmp, k--);
        }
        int res = 0;
        int[][] dp = new int[n][m];
        //初始化dp
        //直接初始第一行和第一列
        for (int i = 0; i < m; i++) {
            if (map.containsKey(board[0][i])) {
                dp[0][i] = map.get(board[0][i]);
            }
        }

        for (int i = 0; i < n; i++) {
            if (map.containsKey(board[i][0])) {
                dp[i][0] = map.get(board[i][0]);
            }
        }
        for (int i = 1; i < n; ++i) {
            for (int j = 1; j < m; ++j) {
                char tmp = board[i][j];
                if (map.containsKey(tmp)) {
                    dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]) + map.get(tmp);
                } else {
                    dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
                }
            }
        }

        System.out.println(dp[n - 1][m - 1]);
    }
    public static void main777(String[] args) {
        Map<Integer, Integer> map = new HashMap<>();
        Scanner scan = new Scanner(System.in);

        // 输入行数和列数
        System.out.print("请输入二维数组的行数：      到头了 ");
        System.out.println("我是废物");
        int rows = scan.nextInt();
        System.out.print("请输入二维数组的列数：  ");
        int cols = scan.nextInt();

        // 创建二维字符数组
        char[][] matrix = new char[rows][cols];

        // 输入矩阵元素
        System.out.println("请输入二维字符矩阵：");
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                matrix[i][j] = scan.next().charAt(0); // 读取单个字符
            }
        }

        // 输出矩阵
        System.out.println("输入的二维字符矩阵为： ");
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                System.out.print(matrix[i][j] + " ");
            }
            System.out.println();
        }
    }
    public static void main666(String[] args) {

        Scanner in = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
        int n = in.nextInt();
        int m = in.nextInt();

        char[][] board = new char[n][m];
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < m; ++j) {

            }
        }
//        Arrays.sort(new int[] {1,2,3,4});
//        int[] c = {1,2,3,5};
//        Arrays.sort(c);
//        int a = 10;
//        int b = 122;
//        while (a % b != 0) {
//            int tmp = a % b;
//            a = b;
//            b = tmp;
//        }
//
//        System.out.println(b);

    }
    public static String removeKdigits(String num, int k) {
        Deque<Character> deque = new LinkedList<Character>();
        int length = num.length();
        for (int i = 0; i < length; ++i) {
            char digit = num.charAt(i);
            while (!deque.isEmpty() && k > 0 && deque.peekLast() > digit) {
                deque.pollLast();
                k--;
            }
            deque.offerLast(digit);
        }
        for (char tmp : deque) {
            System.out.println(tmp);
        }

        for (int i = 0; i < k; ++i) {
            deque.pollLast();
        }
        System.out.println("++++++++++++");
        for (char tmp : deque) {
            System.out.println(tmp);
        }

        StringBuilder ret = new StringBuilder();
        boolean leadingZero = true;
        while (!deque.isEmpty()) {
            char digit = deque.pollFirst();
            if (leadingZero && digit == '0') {
                continue;
            }
            leadingZero = false;
            ret.append(digit);
        }
        return ret.length() == 0 ? "0" : ret.toString();
    }

    public static void main34(String[] args) {
        String s = "1432219";
        Scanner scanner = new Scanner(System.in);
        int a = scanner.nextInt();

        removeKdigits(s, 3);
    }
    public static int maxRotateFunction1(int[] nums) {
        int n = nums.length;
        int[] sum = new int[n * 2 + 10];
        for (int i = 1; i <= 2 * n; i++) sum[i] = sum[i - 1] + nums[(i - 1) % n];
        for (int tmp : sum) {
            System.out.print(tmp + " ");
        }
        int ans = 0;
        for (int i = 1; i <= n; i++) ans += nums[i - 1] * (i - 1);
        for (int i = n + 1, cur = ans; i < 2 * n; i++) {
            cur += nums[(i - 1) % n] * (n - 1);
            cur -= sum[i - 1] - sum[i - n];
            if (cur > ans) ans = cur;
        }
        return ans;
    }


    public static int maxRotateFunction(int[] nums) {
        //其实也很简单
        //我们将nums再一次进行拼接即可
        //之后利用滑动窗口 和 前缀和
        int n = nums.length;
        int[] sum = new int[2 * n];

        sum[0] = nums[0];
        for (int i = 1; i < 2 * n; i++) {
            sum[i] = sum[i - 1] + nums[i % n];
        }

        for (int tmp : sum) {
            System.out.print(tmp + " ");
        }

        int ans = 0;
        //先初始化窗口中的值
        for (int i = 1; i <= n; ++i) {
            ans += nums[i - 1] * (i - 1);
        }
        int cur = ans;
        for (int i = n + 1; i < 2 * n; ++i) {
            //i = n + 1 相当于新加入的值的下标
            cur += nums[(i - 1) % n] * (n - 1);
            //此时还需要减去刚才的公共部分
            //就相当于把上一次的多减去一次
            cur -= sum[i - 1] - sum[i - n];
            ans = Math.max(ans, cur);
        }

        return ans;
    }

    public static void main1111(String[] args) {
        int[] nums = {4,3,2,6};
        maxRotateFunction(nums);
        System.out.println();
        maxRotateFunction1(nums);
    }
    public static void main10(String[] args) {
        StringBuilder a = new StringBuilder();
        System.out.println("acdd");
        System.out.print(a.toString());
        System.out.println("aaaabbb");
        List<String> res = new LinkedList<>();
        System.out.println("------------");
        res.add(a.toString());
        System.out.println(res.get(0));
        res.add("abc");
        for (String tmp : res) {
            System.out.println(tmp);
        }

        String tmp = "acdd";
        for (String s : tmp.split("c")) {
            System.out.println(s);
        }
    }


    public static void main9(String[] args) {
        int i = 0;
        for (; i < 5; i++) {

        }
        System.out.println(i);
        System.out.println("kun1266666");
        System.out.println("没事复习一下丑数");
        System.out.println("很难113");
        StringBuilder sb = new StringBuilder();
        sb.append("aa");
        sb.append("badcll来来来没学哈哈啦啦哈哈65656569啊啊啊");
        int c = Integer.MAX_VALUE;
        sb.reverse();
    }
    public static int findDuplicate(int[] nums) {
        int slow = 0, fast = 0;
        do {
            slow = nums[slow];
            fast = nums[nums[fast]];
            System.out.println("slow = " + slow + " fast = " + fast);
        } while (slow != fast);
        slow = 0;
        System.out.println("------------");
        System.out.println(slow + " " + fast);
        while (slow != fast) {
            slow = nums[slow];
            fast = nums[fast];
            System.out.println("slow = " + slow + " fast = " + fast);
        }
        return slow;

    }

    public static void main6(String[] args) {
        int[] nums = {3,1,3,4,2};
        Stack<Integer> stack = new Stack<>();
        findDuplicate(nums);
        System.out.println("bu");

    }

    public static void main7(String[] args) {
        int k = 0;
        System.out.println(k + 'a');
        System.out.println('a' + 1);
        char a = 'a' + 2;
        System.out.println(a);
        String ss = "aaaa";
        ss.toCharArray();
        char aaa = 'c';
        String cs = ss.toString();
        System.out.println(cs);
    }

    public static int maxIncreasingCells(int[][] mat) {
        // 动态规划，每个位置都可以从它所在的行和列中严格小于它的位置转移过来
        // 从哪个位置转移呢？肯定是从访问单元格最大数量的那个转移过来，即要维护每一行和每一列中访问单元格数目的最大值
        // 为了保证得到的最大值一定是元素小于当前位置的，我们需要对矩阵中的元素进行排序，先处理元素小的再处理元素大的
        int m = mat.length;
        int n = mat[0].length;
        int[] rowMax = new int[m];      // 存储每一行单元格中当前能访问的单元格最大值
        int[] colMax = new int[n];      // 存储每一列单元格中当前能访问的单元格最大值
        TreeMap<Integer, List<Integer>> indexes = new TreeMap<>();  // 有序哈希表，键是元素值，值是这个元素值所在的单元编号列表
        for(int i = 0; i < m; i++){
            for(int j = 0; j < n; j++){
                if(!indexes.containsKey(mat[i][j]))indexes.put(mat[i][j], new ArrayList<>());
                indexes.get(mat[i][j]).add(i * n + j);
            }
        }
        for(List<Integer> ls: indexes.values()){
            int l = ls.size();
            int[] mx = new int[l];
            // 先更新当前值的每个位置的结果
            for(int i = 0; i < l; i++){
                int id = ls.get(i);
                mx[i] = Math.max(rowMax[id / n], colMax[id % n]) + 1;
            }
            // 再更新每一行每一列的最大值，避免更新当前值的时候覆盖了
            System.out.println();
            for(int i = 0; i < l; i++){
                int r = ls.get(i) / n, c = ls.get(i) % n;
                rowMax[r] = Math.max(rowMax[r], mx[i]);
                colMax[c] = Math.max(colMax[c], mx[i]);
            }

            for(int i = 0; i < 2; i++) {
                System.out.println(rowMax[i]);
                System.out.println(colMax[i]);
            }
            System.out.println("--------------");
        }
        int ans = 0;
        for(int mx: rowMax)ans = Math.max(mx, ans);
        return ans;    // 最终最大值一定存在行数组或列数组中
    }

    public static void main3(String[] args) {
        int[][] mat = {{3,1},{3,4}};
        maxIncreasingCells(mat);
        System.out.println("因为太累了，还是困难题，明天解决偶");
    }


    public static void main1(String[] args) {
        int[] n = {1,2,3};

        Solution solution = new Solution(n);
        solution.printNums();
        System.out.println();
        System.out.println("jiu");
        System.out.println("wozaiganma");
        System.out.println("好难5454444111");
        System.out.println("好累");

        int j = 0;
        int a = 2;
        for (; j < 2; j++) {
            System.out.println("1");
        }
        System.out.println(j);
    }




    public static void main2(String[] args) {
        PriorityQueue<Integer> queue = new PriorityQueue<>();
        Stack<Integer> stack = new Stack<>();
        String ret = "123";
        char[] s = ret.toCharArray();
        ret = s.toString();
        StringBuilder ss = new StringBuilder("aaa");
        ss.toString().toCharArray();
        Set<Integer> set = new HashSet<>();
        System.out.println(100 % 1);

        System.out.println("aaaaaa");
        System.out.println();
        System.out.println("火力全开");
    }
}
